<template>
    <!-- 按照栅格系统布局 分成两列 高度为屏幕大小 -->
    <div class="grid grid-cols-2 h-screen">
        <!-- 
        col-span-2：该元素将跨越两列。这意味着它会占据两列的空间。

        order-2：设置该元素在网格中的显示顺序为 2。默认情况下，网格项按照它们在 DOM 中的顺序排列，但你可以使用 order 属性来改变这个顺序。

        md:col-span-1：当屏幕宽度达到中等尺寸（md）及以上时，该元素将只跨越一列。md 是 Tailwind CSS 中的一个断点，默认是 768px。

        md:order-1：当屏幕宽度达到中等尺寸（md）及以上时，该元素的显示顺序将变为 1。

        bg-black：设置该元素的背景颜色为黑色。
        
        -->
        <!-- 左边栏 -->
        <div class="col-span-2 order-2 md:col-span-1 md:order-1 bg-black
            animate__animated animate__bounceInLeft animate__fast
        ">
            <!-- 指定为 flex 布局，并设置为屏幕垂直水平居中，高度为 100% -->
            <div class="flex justify-center items-center h-full flex-col">
                <h2 class="font-bold text-4xl mb-7 text-white">Weblog 博客登录</h2>
                <p class="text-white">一款由 Spring Boot + Mybaits Plus + Vue 3.2 + Vite 4 开发的前后端分离博客。</p>
                <!-- 指定图片宽度为父级元素的 100%，高度为 100%，并使用 object-cover 保持图片的宽高比 -->
                <img src="@/assets/thw.png" class="w-1/2 object-cover">
            </div>
        </div>
        <!-- 右边栏 -->
        <div
        class="flex flex-col col-span-2 order-1 md:col-span-1 md:order-2 bg-white dark:bg-gray-800">
            <!-- 白天黑夜开关，ml-auto 靠右显示 -->
            <label class="switch ml-auto mt-4 mr-4">
                <input type="checkbox" v-model="isLight" @click="toggleDark()">
                <span class="slider"></span>
            </label>
            <div class="flex justify-center items-center h-full flex-col">
                <!-- 大标题，设置字体粗细、大小、下边距 -->
                <h1 class="font-bold text-4xl mb-5 dark:text-white">欢迎回来</h1>
                <!-- 设置 flex 布局，内容垂直水平居中，文字颜色，以及子内容水平方向 x 轴间距 -->
                <div class="flex items-center justify-center mb-7 text-gray-400 space-x-2 dark:text-gray-500">
                    <!-- 左边横线，高度为 1px, 宽度为 16，背景色设置 -->
                    <span class="h-[1px] w-16 bg-gray-200 dark:bg-gray-700"></span>
                    <span>账号密码登录</span>
                    <!-- 右边横线 -->
                    <span class="h-[1px] w-16 bg-gray-200 dark:bg-gray-700"></span>
                </div>
                <!-- 引入 Element Plus 表单组件，移动端设置宽度为 5/6，PC 端设置为 2/5 -->
                <el-form class="w-5/6 md:w-2/5" ref="login_formRef" :rules="login_rules" :model="login_form">
                    <el-form-item prop="username">
                        <!-- 输入框组件 -->
                        <el-input size="large" placeholder="请输入用户名" v-model="login_form.username" :prefix-icon="User"
                            clearable />
                    </el-form-item>
                    <el-form-item prop="password">
                        <!-- 密码框组件 -->
                        <el-input size="large" type="password" placeholder="请输入密码" v-model="login_form.password"
                            :prefix-icon="Lock" clearable show-password />
                    </el-form-item>
                    <el-form-item>
                        <!-- 登录按钮，宽度设置为 100% -->
                        <el-button class="w-full" size="large" type="primary" @click="onSubmit">登录</el-button>
                    </el-form-item>
                    <el-form-item>
                        <!-- 登录按钮，宽度设置为 100% -->
                        <el-button class="w-full" size="large" type="primary"  @click="dialogVisible = true">修改密码</el-button>
                    </el-form-item>
                </el-form>

            </div>
        </div>
    </div>


    <!-- 修改密码的对话框 -->
    <el-dialog
        v-model="dialogVisible"
        title="修改密码"
        width="500"
        :before-close="handleClose"
    >
    <el-form  ref="update_formRef"   :rules="update_rules" :model="update_form" > 
        <el-form-item prop="username">
            <el-input size="large" placeholder="请输入用户名" v-model="update_form.username" :prefix-icon="User"
                clearable />
        </el-form-item>
        <el-form-item prop="email">
            <el-input size="large" type="email" placeholder="请输入邮箱" v-model="update_form.email"
                :prefix-icon="Promotion" clearable />
        </el-form-item>
        <el-form-item prop="newPassword">
            <el-input size="large" type="password" placeholder="请输入新密码" v-model="update_form.newPassword"
                :prefix-icon="Lock" clearable show-password />
        </el-form-item>
        <el-form-item prop="code" :inline="true">
            <div class="flex items-center gap-2 w-468">
                <el-input 
                size="large" 
                type="text" 
                placeholder="请输入验证码" 
                v-model="update_form.code"
                :prefix-icon="Message" 
                clearable 
                class="w-300" 
                />
                <el-button 
                size="large" 
                @click="sendCode(update_form)"
                type="primary"
                class="w-60"
                >
                {{ countdown > 0 ? `${countdown}s后重新发送` : '发送验证码' }}
                </el-button>
            </div>
        </el-form-item>
    </el-form>
    
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancelDialog">取消</el-button>
        <!-- 此处添加事件进行监听并提交表单 -->
        <el-button type="primary" @click="handUpdatePassword">
          确认
        </el-button>
      </div>
    </template>
    </el-dialog>
</template>



<script setup>
// 引入 Element Plus 中的用户、锁图标
import { User, Lock , Promotion,Message } from '@element-plus/icons-vue'
import { ElMessageBox,ElNotification  } from 'element-plus'
import { login,sendVerifyCode,updatePassword} from '@/api/admin/user'
import { useRouter } from 'vue-router';
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { showMessage } from '@/composables/utils';
import { setToken } from '@/composables/auth'
import { useUserStore } from '@/stores/user'
import { useDark, useToggle } from '@vueuse/core'
// 是否是白天
const isLight = ref(true)
const isDark = useDark({
  onChanged(dark) {
    // update the dom, call the API or something
    console.log('onchange:' + dark)
    if (dark) {
        // 给 body 添加 class="dark"
        document.documentElement.classList.add('dark');
        // 设置 switch 的值
        isLight.value = false
    } else {
        // 移除 body 中添加 class="dark"
        document.documentElement.classList.remove('dark');
        isLight.value = true
    }
  },
})
const toggleDark = useToggle(isDark)
// 是否显示对话框 默认值 false
const dialogVisible = ref(false)

//全局用户管理
const userStore = useUserStore()

// 引入路由 对象 使用路由跳转
const router = useRouter()
/**
 * 
 * ref(null):

ref 是 Vue 3 提供的一个函数，用于创建一个响应式的数据对象。
参数 null 表示这个引用的初始值为 null。
返回的对象有一个 .value 属性，用来访问和修改这个引用的实际值。
const formRef = ref(null):

将 ref(null) 的返回值赋给常量 formRef。
formRef 是一个响应式的引用，它的初始值为 null。
在后续的代码中，可以通过 formRef.value 来访问或修改这个引用的值。
 * 
 */
const login_formRef = ref(null)
const update_formRef = ref(null)
// 添加倒计时相关的响应式数据
const countdown = ref(0)
const countdownTimer = ref(null)
// 定义响应式的表单对象 用户登录需要的参数
const login_form = reactive({
    username: '',
    password: '',
})
// 定义响应式的表单对象  用户修改密码需要的参数
const update_form = reactive({
    username: '',
    email: '',
    newPassword: '',
    code: '',
})

// 用户登录表单验证规则
const login_rules = reactive({
    username: [
        {
            required: true,
            message: '请输入用户名',
            trigger: 'blur'
        }
    ],
    password: [
        {
            required: true,
            message: '请输入密码',
            trigger: 'blur'
        }
    ]
})
// 用户修改密码表单验证规则
const update_rules = reactive({
    username: [
        {
            required: true,
            message: '请输入用户名',
            trigger: 'blur'
        }
    ],
    email: [
        {
            required: true,
            message: '请输入邮箱',
            trigger: 'blur'
        },
        {
            pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
            message: '请输入正确的邮箱格式',
            trigger: 'blur'
        }
    ],
    newPassword: [
        {
            required: true,
            message: '请输入新密码',
            trigger: 'blur'
        }
    ],
    code: [
        {
            required: true,
            message: '请输入验证码',
            trigger: 'blur'
        }
    ]
})
// 登录按钮加载
const loading = ref(false)

// 按回车键后，执行登录事件
function onKeyUp(e) {
    console.log(e)
    if (e.key == 'Enter') {
        onSubmit()
    }
}

// 添加键盘监听
onMounted(() => {
    console.log('添加键盘监听')
    document.addEventListener('keyup', onKeyUp)
})

// 移除键盘监听
onBeforeUnmount(() => {
    document.removeEventListener('keyup', onKeyUp)
})

// 登录
const onSubmit = () => {
    // 先验证 form 表单字段
    login_formRef.value.validate((valid) => {
        console.log(valid)
        if (!valid) {
            showMessage('请输入用户名或密码', 'error')
            return false
        }

        // 开始加载
        loading.value = true

        // 调用登录接口
        login(login_form.username, login_form.password).then((res) => {
            console.log(res)
            // 判断是否成功
            if (res.success == true) {
                showMessage("登陆成功", 'success')
                // 跳转到后台首页
                // 存储 Token 到 Cookie 中
                let token = res.data.token
                setToken(token)
                //将用户信息存储到全局store中去
                //主动调用了 setUserInfo() 方法 方法中发送请求 获取用户信息
                userStore.setUserInfo()
                console.log(userStore.userInfo.value)
                router.push('/admin/index')
            } else {
                showMessage(res.message, 'error')
            }
        })

            .finally(() => {
                // 结束加载
                loading.value = false
            })
    })
}

// 监听密码对话框的关闭事件 
const handleClose = (done) => {
  ElMessageBox.confirm('是否确认关闭对话框?')
    .then(() => {
      console.log('取消了修改密码的对话框')
      //清楚计时器
      countdown.value = 0
      clearInterval(countdownTimer.value)
      done()
    })
    .catch(() => {
        // catch error 捕获错误 进行错误处理
    })
}
// 点击对话框中的取消按钮
const cancelDialog = () => { 
    dialogVisible.value = false
    console.log('取消了修改密码的对话框')
    //清楚计时器
    countdown.value = 0
    clearInterval(countdownTimer.value)
}
// 发送验证码
const sendCode = (data) => { 

    // 第一步检查是否已经发送过验证码 发送过则提示已发送
    if (countdown.value > 0) {
        ElNotification.info({
            title: '提示',
            message: '已发送验证码，请勿重复发送',
            duration: 3000,
        })
        showMessage('已发送验证码，请勿重复发送', 'warning')
        return
    }
    // 对参数进行再一次校验
    if (!data.email) {
        showMessage('请输入邮箱', 'error')
        return
    }
    if (!data.username) {
        showMessage('请输入用户名', 'error')
        return
    }
     // 开始加载
    loading.value = true

    //请求发送ok 开启倒计时并且提示消息弹窗
    sendVerifyCode(data.username, data.email).then(res => { 
         console.log(res)
         // 判断是否成功
        if (res.success == true) {
            showMessage('验证码发送成功，有效时间120秒')
            ElNotification({
            title: 'Success',
            message: '已发送验证码，请勿重复发送，验证码有效期是120秒',
            type: 'success',
            duration: 3000,
            })
            // 开始倒计时
            handleTimer()
        } else {
            showMessage(res.message, 'error')
        }

    }).finally(() => {
      loading.value = false
    })
   
}
//修改密码的请求
// 修改 handUpdatePassword 函数
const handUpdatePassword = () => { 
    update_formRef.value.validate((valid) => {
        // 修复参数名：varid -> valid
        if (!valid) {
            return false;
        }
        
        // 发送请求
        // 开始加载
        loading.value = true;

        // 修复变量名：update_from -> update_form
        updatePassword(update_form).then((res) => { 
            if (res.success == true) {
                showMessage(res.message, 'success');
                ElNotification({
                    title: 'Success',
                    message: '用户密码修改成功',
                    type: 'success',
                    duration: 3000,
                });
                dialogVisible.value = false;
                // 清除计时器
                countdown.value = 0;
                clearInterval(countdownTimer.value);
            } else {
                showMessage(res.message, 'error');
            }
        }).finally(() => { 
            // 关闭组件的加载动画
            loading.value = false;
        });
    });
};
// 处理计时器的方法
const handleTimer = () => { 
    countdown.value = 120 
    // 清除之前的定时器
    if (countdownTimer.value) {
        clearInterval(countdownTimer.value)
    }
    
    // 启动倒计时
    countdownTimer.value = setInterval(() => {
        countdown.value--
        if (countdown.value <= 0) {
            clearInterval(countdownTimer.value)
            countdownTimer.value = null
        }
    }, 1000)
}
</script>


<style scoped>
/* The switch - the box around the slider */
.switch {
  font-size: 14px;
  position: relative;
  display: inline-block;
  width: 3.5em;
  height: 2em;
}

/* Hide default HTML checkbox */
.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

/* The slider */
.slider {
  --background: #28096b;
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: var(--background);
  transition: .5s;
  border-radius: 30px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 1.4em;
  width: 1.4em;
  border-radius: 50%;
  left: 10%;
  bottom: 15%;
  box-shadow: inset 8px -4px 0px 0px #fff000;
  background: var(--background);
  transition: .5s;
}

input:checked + .slider {
  background-color: #522ba7;
}

input:checked + .slider:before {
  transform: translateX(100%);
  box-shadow: inset 15px -4px 0px 15px #fff000;
}
</style>
